package bob.project.inventory;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import bob.project.ResourceManager;
import bob.project.inventory.def.AmmoItemDef;
import bob.project.inventory.def.HealItemDef;
import bob.project.inventory.def.ItemDef;
import bob.project.inventory.def.WeaponItemDef;

public class ItemManager
{
	public static Map<Integer,ItemDef> items;
	
	
	public static void init()
	{
		items = new HashMap<Integer,ItemDef>();
		InputStream is = ResourceManager.class.getResourceAsStream("items.xml");
        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = null;
        Document doc = null;
		try {
			docBuilder = docBuilderFactory.newDocumentBuilder();
			doc = docBuilder.parse (is);
			doc.getDocumentElement ().normalize ();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
        NodeList objects = doc.getElementsByTagName("item");
        for(int s=0; s<objects.getLength() ; s++)
        {
            Node obj = objects.item(s);
            if (obj.getAttributes() != null)
            {
            	System.out.println(obj.getAttributes().getNamedItem("type").getNodeValue());
            	if (obj.getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("other"))
            	{
            		loadItem(obj);
            	}
            	if (obj.getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("ammo"))
            	{
            		loadAmmo(obj);
            	}
            	if (obj.getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("weapon"))
            	{
            		loadWeapon(obj);
            	}
            	if (obj.getAttributes().getNamedItem("type").getNodeValue().equalsIgnoreCase("heal"))
            	{
            		loadHeal(obj);
            	}
            }
        }
        
        int count = items.size();
        System.out.println("ItemManager : total loaded " + count);
	}


	private static void loadHeal(Node obj)
	{
		HealItemDef item = new HealItemDef();
        for(int s=0; s<obj.getChildNodes().getLength() ; s++)
		{
        	 Node node = obj.getChildNodes().item(s);
          	 
        	 if (node.getNodeName() == "id")
        		 item.itemId = Integer.parseInt(node.getTextContent());
        	 if (node.getNodeName() == "name")
        		 item.name = node.getTextContent();
        	 if (node.getNodeName() == "icon")
        		 item.icon = node.getTextContent();
        	 if (node.getNodeName() == "image")
        		 item.image = node.getTextContent();
        	 if (node.getNodeName() == "tooltip")
        		 item.tooltip = node.getTextContent();
        	 if (node.getNodeName() == "stackable")
        		 item.isStack = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "dropable")
        		 item.canDrop = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "removable")
        		 item.canDelete = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "power")
        		 item.healPower = Integer.parseInt(node.getTextContent());
		}
        items.put(item.itemId,item);
		
	}


	private static void loadAmmo(Node obj)
	{
		AmmoItemDef item = new AmmoItemDef();
        for(int s=0; s<obj.getChildNodes().getLength() ; s++)
		{
        	 Node node = obj.getChildNodes().item(s);
          	 
        	 if (node.getNodeName() == "id")
        		 item.itemId = Integer.parseInt(node.getTextContent());
        	 if (node.getNodeName() == "name")
        		 item.name = node.getTextContent();
        	 if (node.getNodeName() == "icon")
        		 item.icon = node.getTextContent();
        	 if (node.getNodeName() == "image")
        		 item.image = node.getTextContent();
        	 if (node.getNodeName() == "tooltip")
        		 item.tooltip = node.getTextContent();
        	 if (node.getNodeName() == "stackable")
        		 item.isStack = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "dropable")
        		 item.canDrop = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "removable")
        		 item.canDelete = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "forWeapon")
        		 item.forWeaponId = Integer.parseInt(node.getTextContent());
        	 if (node.getNodeName() == "ammoCount")
        		 item.count = Integer.parseInt(node.getTextContent());
		}
        items.put(item.itemId,item);
		
	}


	private static void loadWeapon(Node obj)
	{
		WeaponItemDef item = new WeaponItemDef();
        for(int s=0; s<obj.getChildNodes().getLength() ; s++)
		{
        	 Node node = obj.getChildNodes().item(s);
        	 if (node.getNodeName() == "id")
        		 item.itemId = Integer.parseInt(node.getTextContent());
        	 if (node.getNodeName() == "name")
        		 item.name = node.getTextContent();
        	 if (node.getNodeName() == "icon")
        		 item.icon = node.getTextContent();
        	 if (node.getNodeName() == "image")
        		 item.image = node.getTextContent();
        	 if (node.getNodeName() == "tooltip")
        		 item.tooltip = node.getTextContent();
        	 if (node.getNodeName() == "stackable")
        		 item.isStack = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "dropable")
        		 item.canDrop = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "removable")
        		 item.canDelete = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "power")
        		 item.power = Integer.parseInt(node.getTextContent());
        	 if (node.getNodeName() == "reload")
        		 item.reloadTime = Integer.parseInt(node.getTextContent());
        	 if (node.getNodeName() == "fullLoad")
        		 item.fullLoad = Integer.parseInt(node.getTextContent());
		}
        items.put(item.itemId,item);
	}


	private static void loadItem(Node obj)
	{
		ItemDef item = new ItemDef();
        for(int s=0; s<obj.getChildNodes().getLength() ; s++)
		{
        	 Node node = obj.getChildNodes().item(s);
        	 if (node.getNodeName() == "id")
        		 item.itemId = Integer.parseInt(node.getTextContent());
        	 if (node.getNodeName() == "name")
        		 item.name = node.getTextContent();
        	 if (node.getNodeName() == "icon")
        		 item.icon = node.getTextContent();
        	 if (node.getNodeName() == "image")
        		 item.image = node.getTextContent();
        	 if (node.getNodeName() == "tooltip")
        		 item.tooltip = node.getTextContent();
        	 if (node.getNodeName() == "stackable")
        		 item.isStack = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "dropable")
        		 item.canDrop = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "removable")
        		 item.canDelete = Boolean.parseBoolean(node.getTextContent());
        	 if (node.getNodeName() == "type")
        		 item.type = Integer.parseInt(node.getTextContent());
		}
        items.put(item.itemId,item);
	}
	
	public static Item createItemById(int id)
	{
		if (!items.containsKey(id))
			return null;
		
		ItemDef def = items.get(id);
		Item result = null;
		
		if (def instanceof AmmoItemDef)
			result = new AmmoItem((AmmoItemDef) def);
		else if(def instanceof HealItemDef)
			result = new HealItem((HealItemDef) def);
		else if(def instanceof WeaponItemDef)
			result = new WeaponItem((WeaponItemDef) def);
		else
			result = new Item(def);
		return result;
	}
}
